#pragma once

#include <windows.h>


#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC         ((USHORT) 0x01)
#endif

#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE        ((USHORT) 0x02)
#endif

#ifndef HID_USAGE_GENERIC_KEYBOARD
#define HID_USAGE_GENERIC_KEYBOARD		((USHORT)0x06)
#endif

#ifndef HID_USAGE_GENERIC_GAMEPAD
#define HID_USAGE_GENERIC_GAMEPAD		((USHORT)0x05)
#endif

#ifndef HID_USAGE_GENERIC_JOYSTICK
#define HID_USAGE_GENERIC_JOYSTICK		((USHORT)0x04)
#endif


#define CASGE_LBUTTON	0x00000001
#define CASGE_RBUTTON	0x00000010


class CD3D9Engine;
class CInputHID
{
	protected:
		bool CreateInputListener(HWND hwnd);

		void Update(RAWINPUT* rawData, UINT numRawData = 0, bool background = false);
		void ResetOnIdle();

		bool			_bufferedKeys;

		void SetAbsMouseCoordinates(UINT x, UINT y) 
		{
			_mouseInfo.posXabsolute = x;
			_mouseInfo.posYabsolute = y;
		}

	private:
		RAWINPUTDEVICE	_rawDevice;

		struct SMOUSE_INFO
		{
			int posXrelative;
			int posYrelative;
			int posXabsolute;
			int posYabsolute;

			bool btn1Down;
			bool btn2Down;
			bool btn3Down;

			int wheelDelta;
		} _mouseInfo;

		struct SKEYBOARD_INFO
		{
			USHORT keyPressed[5];

		} _keyboardInfo;

		unsigned int _MousePosX;
		unsigned int _MousePosY;
		unsigned int _MouseButtonFlags;
		bool _keys[256];

	public:
		CInputHID()
		{
			memset(&_mouseInfo, 0, sizeof(_mouseInfo));
			memset(&_keyboardInfo, 0, sizeof(_keyboardInfo));

			POINT p;
			GetCursorPos(&p);

			_mouseInfo.posXabsolute = p.x;
			_mouseInfo.posYabsolute = p.y;

			_bufferedKeys = false;

			memset(&_keys, 0, sizeof(_keys));
			_MousePosX = _MousePosY = _MouseButtonFlags = 0;
		}
		
		~CInputHID() {}

		friend class CD3D9Engine;


		//********
		bool GetFMouseLeft() const { return _mouseInfo.btn1Down; }
		bool GetFMouseRight() const { return _mouseInfo.btn2Down; }
		bool GetFMouseMiddle() const { return _mouseInfo.btn3Down; }

		//bool GetSMouseLeft() const { return (_MouseButtonFlags & CASGE_LBUTTON); }
		//bool GetSMouseRight() const  { return (_MouseButtonFlags & CASGE_RBUTTON); }

		UINT GetFMouseXAbs() const { return _mouseInfo.posXabsolute; }
		UINT GetFMouseYAbs() const { return _mouseInfo.posYabsolute; }
		signed int GetFMouseXRel() const { return _mouseInfo.posXrelative; }
		signed int GetFMouseYRel() const { return _mouseInfo.posYrelative; }

		UINT GetSMouseX() const { return _MousePosX; }
		UINT GetSMouseY() const { return _MousePosY; }

		bool GetFMouseWheepUp() const { return _mouseInfo.wheelDelta > 0; }
		bool GetFMouseWheepDown() const { return _mouseInfo.wheelDelta < 0; }

		bool GetFKeyIsDown(USHORT key) const
		{ 
			return (_keyboardInfo.keyPressed[0] == key ||
					_keyboardInfo.keyPressed[1] == key ||
					_keyboardInfo.keyPressed[2] == key ||
					_keyboardInfo.keyPressed[3] == key ||
					_keyboardInfo.keyPressed[4] == key); 
		}


		bool GetSKeyIsDown(USHORT key) const
		{
			return _keys[key];
		}

		char GetSKeyPressed() const
		{
			for(int i=0; i<256; ++i)
				if(_keys[i])
					return (char)i;

			return -1;
		}
};